import * as path from 'path';
import * as fs from 'fs';
import { Logger } from '../../../../src/logger/Logger';
import { FuzzerStructure } from '../types/FuzzTypes';

/**
 * Fuzz 目录结构创建器
 * 负责创建 Fuzzer 所需的目录结构
 */
export class FuzzStructureCreator {
    /**
     * 查找项目根目录
     * @param startDir 起始目录
     * @returns 项目根目录路径
     */
    public static findProjectRoot(startDir: string): string {
        let projectRoot = startDir;
        let depth = 0;
        const maxDepth = 10;

        while (depth < maxDepth) {
            const parentDir = path.dirname(projectRoot);
            if (parentDir === projectRoot) {
                break;
            }
            
            // 检查是否有特征文件/目录
            const hasOhosConfig = fs.existsSync(path.join(projectRoot, 'ohos.build'));
            const hasBuildGn = fs.existsSync(path.join(projectRoot, 'BUILD.gn'));
            const hasTestDir = fs.existsSync(path.join(projectRoot, 'test'));
            
            if (hasOhosConfig || (hasBuildGn && hasTestDir)) {
                Logger.info(`[FuzzStructureCreator] 找到项目根目录: ${projectRoot}`);
                break;
            }
            
            projectRoot = parentDir;
            depth++;
        }
        
        return projectRoot;
    }

    /**
     * 从源文件目录开始向上查找 test/fuzztest 或 test/fuzz 目录
     * @param sourceFileDir 源文件所在目录
     * @returns 找到的 fuzztest 目录路径，如果找不到则返回 null
     */
    public static findFuzzTestDirectory(sourceFileDir: string): string | null {
        let currentDir = sourceFileDir;
        let depth = 0;
        const maxDepth = 5;

        Logger.info(`[FuzzStructureCreator] 从 ${sourceFileDir} 开始查找 fuzztest 目录...`);

        while (depth < maxDepth) {
            // 检查当前目录下的 test/fuzztest 或 test/fuzz
            const possiblePaths = [
                path.join(currentDir, 'test', 'fuzztest'),
                path.join(currentDir, 'test', 'fuzz'),
                path.join(currentDir, 'tests', 'fuzztest'),
                path.join(currentDir, 'tests', 'fuzz'),
            ];

            for (const testPath of possiblePaths) {
                if (fs.existsSync(testPath)) {
                    Logger.info(`[FuzzStructureCreator] ✅ 找到现有 fuzztest 目录: ${testPath}`);
                    return testPath;
                }
            }

            // 向上一级目录
            const parentDir = path.dirname(currentDir);
            if (parentDir === currentDir) {
                break; // 已到根目录
            }
            currentDir = parentDir;
            depth++;
        }

        Logger.info(`[FuzzStructureCreator] ⚠️ 未找到现有 fuzztest 目录`);
        return null;
    }

    /**
     * 创建 Fuzzer 目录结构
     * @param sourceFilePath 源文件路径
     * @param fuzzerName Fuzzer 名称
     * @returns 目录结构信息
     */
    public static createFuzzerStructure(sourceFilePath: string, fuzzerName: string): FuzzerStructure {
        const sourceFileDir = path.dirname(sourceFilePath);
        
        // 查找现有的 fuzztest 目录
        let fuzzTestDir = this.findFuzzTestDirectory(sourceFileDir);
        
        // 如果找不到，在项目根目录创建
        if (!fuzzTestDir) {
            const projectRoot = this.findProjectRoot(sourceFileDir);
            fuzzTestDir = path.join(projectRoot, 'test', 'fuzztest');
            Logger.info(`[FuzzStructureCreator] 将在项目根创建 fuzztest 目录: ${fuzzTestDir}`);
        }
        
        const projectRoot = this.findProjectRoot(sourceFileDir);
        const fuzzerDir = path.join(fuzzTestDir, fuzzerName);
        const corpusDir = path.join(fuzzerDir, 'corpus');

        // 创建目录结构
        if (!fs.existsSync(fuzzTestDir)) {
            fs.mkdirSync(fuzzTestDir, { recursive: true });
            Logger.info(`[FuzzStructureCreator] 创建 fuzztest 目录: ${fuzzTestDir}`);
        }
        
        if (!fs.existsSync(fuzzerDir)) {
            fs.mkdirSync(fuzzerDir, { recursive: true });
            Logger.info(`[FuzzStructureCreator] 创建 fuzzer 目录: ${fuzzerDir}`);
        }
        
        if (!fs.existsSync(corpusDir)) {
            fs.mkdirSync(corpusDir, { recursive: true });
            Logger.info(`[FuzzStructureCreator] 创建 corpus 目录: ${corpusDir}`);
        }

        return {
            fuzzerDir,
            projectRoot,
            fuzzTestDir,
            corpusDir
        };
    }

    /**
     * 生成目录结构的可视化字符串
     */
    public static visualizeStructure(fuzzerName: string): string {
        return `test/fuzztest/${fuzzerName}/
├── BUILD.gn          (待生成)
├── project.xml       (待生成)
├── ${fuzzerName}.h   (待生成)
├── ${fuzzerName}.cpp (待生成)
└── corpus/
    └── init          (待生成)`;
    }
}

